package com.zwb.wallet.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zwb.wallet.dto.ResultDto;
import com.zwb.wallet.entity.Wallet;
import com.zwb.wallet.mapper.WalletDetailsMapper;
import com.zwb.wallet.entity.WalletDetails;
import com.zwb.wallet.service.WalletDetailsService;
import com.zwb.wallet.service.WalletService;
import com.zwb.wallet.utils.WalletActionType;
import com.zwb.wallet.vo.ConsumptionVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @author 头发又黑又长
 * @Date 2023/2/28 20:55
 * @email zwb15083976291@163.com
 */
@Service
public class WalletDetailsServiceImpl extends ServiceImpl<WalletDetailsMapper, WalletDetails>
        implements WalletDetailsService {

    @Resource
    WalletService walletService;


    @Override
    @Transactional
    public ResultDto consumption(Integer userId, ConsumptionVo consumptionVo) {

        Wallet wallet = walletService.findBalanceByUserId(userId);
        // 钱包余额不足
        if (1 != wallet.getAmountMoney().compareTo(consumptionVo.getMoney())) {
            return new ResultDto(false, "钱包余额不足");
        }




        /*
         *
         * 根据 consumptionVo.getMessage() 中的单号，去查询是否存在真实消费逻辑，
         * 这里的业务根据具体逻辑修改，
         *下面直接写逻辑成功的代码
         * */


        /* 添加明细 */
        WalletDetails walletDetails = new WalletDetails();
        walletDetails.setOrderId(consumptionVo.getOrderId());
        walletDetails.setUserId(wallet.getUserId());
        walletDetails.setType(WalletActionType.CONSUMPTION.getActionType());
        walletDetails.setTypeName(WalletActionType.CONSUMPTION.getActionName());
        walletDetails.setStatus(1);
        walletDetails.setBefAmountMoney(wallet.getAmountMoney());
        walletDetails.setAltAmountMoney(wallet.getAmountMoney().subtract(consumptionVo.getMoney()));
        this.save(walletDetails);

        /* 修改钱包 */
        wallet.setAmountMoney(wallet.getAmountMoney().subtract(consumptionVo.getMoney()));
        walletService.updateById(wallet);

        return new ResultDto(true, "消费成功");
    }

    @Override
    @Transactional
    public ResultDto refund(Integer userId, ConsumptionVo consumptionVo) {


        /*
         *
         * 根据 consumptionVo.getMessage() 中的单号，去查询是否存真实退款的步骤成功
         *这里的业务需要根据具体逻辑编写，
         *下面直接写逻辑成功的代码
         * */


        /*
         * 这里只简单要求：必须有消费的订单存在，才能进行退款，退款的金额是可以随意指定的，不是一定要把消费的那一单全额退款
         * */

        WalletDetails details = this.getOne(new LambdaQueryWrapper<WalletDetails>()
                .eq(WalletDetails::getOrderId, consumptionVo.getOrderId())
                .eq(WalletDetails::getType, WalletActionType.CONSUMPTION.getActionType())
        );
        if (ObjectUtils.isEmpty(details)) {
            return new ResultDto(false, "订单不存");
        }


        // 消费金额小于退款金额

        // 获取到消费金额
        BigDecimal consumption = details.getBefAmountMoney().subtract(details.getAltAmountMoney());
        if (consumption.compareTo(consumptionVo.getMoney()) == -1){
            return new ResultDto(false, "退款金额错误");
        }


        Wallet wallet = walletService.findBalanceByUserId(userId);

        /* 添加明细 */
        WalletDetails walletDetails = new WalletDetails();
        walletDetails.setOrderId(consumptionVo.getOrderId());
        walletDetails.setUserId(wallet.getUserId());
        walletDetails.setType(WalletActionType.REFUND.getActionType());
        walletDetails.setTypeName(WalletActionType.REFUND.getActionName());
        walletDetails.setStatus(1);
        walletDetails.setBefAmountMoney(wallet.getAmountMoney());
        walletDetails.setAltAmountMoney(wallet.getAmountMoney().add(consumptionVo.getMoney()));
        this.save(walletDetails);


        /* 修改钱包 */
        wallet.setAmountMoney(wallet.getAmountMoney().add(consumptionVo.getMoney()));
        walletService.updateById(wallet);
        return new ResultDto(true, "退款成功");
    }
}
